package io.bio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class BioSocketDemo {
    static class Client {
        /**
         * 客户端
         */
        public static void testClient() {
            try {
                Selector selector = Selector.open();
                // 获取通道
                SocketChannel sc = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8888));
                // 切换成非阻塞模式
                sc.configureBlocking(false);
                sc.register(selector,SelectionKey.OP_READ);
                // 分配制定大小的缓冲区,分配完成后即是写模式
                ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                byteBuffer.put("hellow bio".getBytes());
                // 切换到读模式
                byteBuffer.flip();
                // 从缓冲区中读取数据并写到通道中
                sc.write(byteBuffer);
                //sc.close();
                while(true){
                    if (selector.select()>0){
                        Set<SelectionKey> keys = selector.selectedKeys();
                        Iterator<SelectionKey> iterator = keys.iterator();
                        while(iterator.hasNext()){
                            SelectionKey key = iterator.next();
                            SocketChannel channel = (SocketChannel) key.channel();
                            channel.configureBlocking(false);
                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                            int length = channel.read(buffer);
                            System.out.println(new String(buffer.array(),0,length));
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public static void main(String[] args) {
            testClient();
        }
    }

    static class Server {
        public static void testServer() {
            try {
                // 获取selector 选择器
                Selector selector = Selector.open();
                //获取通道
                ServerSocketChannel ssc = ServerSocketChannel.open();
                ssc.bind(new InetSocketAddress(8888));
                // 设置为非阻塞的
                ssc.configureBlocking(false);

                // 注册到selector 上, 并注册的操作是 “接收”操作
                ssc.register(selector, SelectionKey.OP_ACCEPT);
                while (true) {
                    if (selector.select() > 0) {
                        Set<SelectionKey> keys = selector.selectedKeys();
                        Iterator<SelectionKey> iterator = keys.iterator();
                        while (iterator.hasNext()) {
                            SelectionKey key = iterator.next();
                            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                            if (key.isAcceptable()){
                                SocketChannel sc = ssc.accept();
                                sc.configureBlocking(false);
                                sc.register(key.selector(),SelectionKey.OP_READ);
                                byteBuffer.put("服务端接受连接，你好 client.....".getBytes());
                                byteBuffer.flip();
                                sc.write(byteBuffer);
                                //sc.close();
                            }else if(key.isReadable()){
                                SocketChannel sc = (SocketChannel) key.channel();
                                sc.configureBlocking(false);
                                byteBuffer.clear();
                                int read = sc.read(byteBuffer);
                                System.out.println(new String(byteBuffer.array(),0,read));
                                //sc.close();
                            }
                            iterator.remove();

                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public static void main(String[] args) {
            testServer();
        }
    }
}

